package com.gupaoedu.springframework.mvcframework.webmvc;

import com.gupaoedu.springframework.mvcframework.annotation.MyRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * projectName: my-springframwork
 * packageName: com.gupaoedu.springframework.mvcframework.webmvc
 * Created: 2019/4/15.
 * Auther: baifc
 * Description:
 */
public class MyHandlerAdapter {
    public boolean supports(Object handler){ return (handler instanceof MyHandlerMapping);}

    public MyModelAndView handle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {

        MyHandlerMapping handlerMapping = (MyHandlerMapping)handler;

        Map<String, Integer> paramIndexMapping = new HashMap<>();

        Annotation[][] annotations = handlerMapping.getMethod().getParameterAnnotations();

        for (int i = 0; annotations.length > 0; i++) {
            for (Annotation annotation : annotations[i]) {
                if (annotation instanceof MyRequestParam) {
                    String param = ((MyRequestParam) annotation).value();
                    paramIndexMapping.put(param, i);
                }
            }
        }

        //提取方法中的request和response参数
        Class[] classes = handlerMapping.getMethod().getParameterTypes();

        for (int i =  0; i < classes.length; i++) {
            Class<?> type = classes[i];
            if (type == HttpServletResponse.class || type == HttpServletRequest.class) {
                paramIndexMapping.put(type.getName(), i);
            }
        }

        Map<String, String[]> paramMap = req.getParameterMap();

        Object[] paramValues = new Object[classes.length];

        for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
            String value = Arrays.toString(entry.getValue())
                    .replaceAll("\\[|\\]", "").replaceAll("\\s", ",");

            String paramName = entry.getKey();

            Integer index = paramIndexMapping.get(paramName);
            paramValues[index] = caseStringValue(value, classes[index]);
        }

        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())) {
            int reqIndex = paramIndexMapping.get(HttpServletRequest.class.getName());
            paramValues[reqIndex] = req;
        }

        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())) {
            int respIndex = paramIndexMapping.get(HttpServletResponse.class.getName());
            paramValues[respIndex] = resp;
        }

        Object obj = handlerMapping.getMethod().invoke(handlerMapping.getController(), paramValues);

        if (obj == null || obj instanceof Void ) {
            return null;
        }

        if (obj instanceof MyModelAndView) {
            return (MyModelAndView)obj;
        }

        return null;
    }



    private Object caseStringValue(String value, Class<?> paramsType) {
        if(String.class == paramsType){
            return value;
        }
        //如果是int
        if(Integer.class == paramsType){
            return Integer.valueOf(value);
        }
        else if(Double.class == paramsType){
            return Double.valueOf(value);
        }else {
            if(value != null){
                return value;
            }
            return null;
        }
        //如果还有double或者其他类型，继续加if
        //这时候，我们应该想到策略模式了
        //在这里暂时不实现，希望小伙伴自己来实现

    }
}
